package com.yic.module.mes.service.plan;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yic.module.base.api.erpcentermapping.ErpCenterMappingApi;
import com.yic.module.base.api.erpcentermapping.dto.ErpCenterMappingRespDTO;
import com.yic.module.base.api.factory.FactoryApi;
import com.yic.module.base.api.factory.dto.FactoryRespDTO;
import com.yic.module.base.api.item.ItemApi;
import com.yic.module.base.api.item.dto.ItemRespDTO;
import com.yic.module.mes.dal.dataobject.itemproduce.ItemProduceDO;
import com.yic.module.mes.service.itemproduce.ItemProduceService;
import com.yic.module.system.enums.dict.MesPlanStatusEnum;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import com.yic.module.mes.controller.admin.plan.vo.*;
import com.yic.module.mes.dal.dataobject.plan.PlanDO;
import com.yic.framework.common.pojo.PageResult;

import com.yic.module.mes.convert.plan.PlanConvert;
import com.yic.module.mes.dal.mysql.plan.PlanMapper;

import static com.yic.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yic.module.mes.enums.ErrorCodeConstants.*;

/**
 * 生产计划 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class PlanServiceImpl implements PlanService {

    @Resource
    private PlanMapper planMapper;
    @Resource
    @Lazy
    private ItemProduceService itemProduceService;
    @Resource
    private FactoryApi factoryApi;
    @Resource
    private ItemApi itemApi;


    @Override
    public Long createPlan(PlanCreateReqVO createReqVO) {
        validateCreateOrUpdate(null, createReqVO.getCode());
        // 插入
        PlanDO plan = PlanConvert.INSTANCE.convert(createReqVO);
        planMapper.insert(plan);
        // 返回
        return plan.getId();
    }

    @Override
    public Long syncPlan(PlanSyncReqVO syncReqVO) {
        // 目前只同步油缸工单，其他工厂的工单暂不同步,固定返回成功
        if (!syncReqVO.getFactoryCode().equals("1")) {
            return 0L;
        }
        // 目前只同步油缸5101和5301的单据
        if (!syncReqVO.getType().equals(5101) && !syncReqVO.getType().equals(5301)) {
            return 0L;
        }
        // 处理工厂信息
        FactoryRespDTO factory = factoryApi.getFactory(syncReqVO.getFactoryCode());
        if (ObjectUtil.isEmpty(factory)) {
            throw exception(PLAN_NOT_FOUND_FACTORY, syncReqVO.getCode());
        }
        // 处理产品生产信息
        ItemRespDTO item = itemApi.getItem(syncReqVO.getItemCode());
        if (ObjectUtil.isEmpty(item)) {
            throw exception(PLAN_NOT_FOUND_ITEM, syncReqVO.getCode());
        }
        ItemProduceDO itemProduce = itemProduceService.getItemProduce(factory.getId(), item.getId());
        if (ObjectUtil.isEmpty(itemProduce)) {
            throw exception(PLAN_NOT_FOUND_ITEM, syncReqVO.getCode());
        }
        // 数据扭转
        PlanCreateReqVO createReqVO = new PlanCreateReqVO();
        createReqVO.setCode(syncReqVO.getCode());
        createReqVO.setType(1);
        createReqVO.setItemId(item.getId());
        createReqVO.setItemProduceId(itemProduce.getId());
        createReqVO.setFactoryId(factory.getId());
        createReqVO.setWorkshopId(itemProduce.getWorkshopId());
        createReqVO.setEmergent(syncReqVO.getEmergent());
        createReqVO.setBatchNo(syncReqVO.getBatchNo());
        createReqVO.setRemark(syncReqVO.getRemark());
        createReqVO.setPlanAmount(syncReqVO.getProduceAmount());
        createReqVO.setPlanStartTime(DateUtil.toLocalDateTime(syncReqVO.getPlanStartTime()));
        createReqVO.setPlanCompleteTime(DateUtil.toLocalDateTime(syncReqVO.getPlanCompleteTime()));
        createReqVO.setErpCenterCode(syncReqVO.getCenterCode());
        createReqVO.setErpWarehouseCode(syncReqVO.getWarehouseCode());
        return createPlan(createReqVO);
    }

    @Override
    public void updatePlan(PlanUpdateReqVO updateReqVO) {
        validatePlanChange(updateReqVO.getId());
        // 校验存在
        validateCodeExists(updateReqVO.getId(), updateReqVO.getCode());
        // 更新
        PlanDO updateObj = PlanConvert.INSTANCE.convert(updateReqVO);
        planMapper.updateById(updateObj);
    }

    @Override
    public void batchUpdatePlan(Collection<PlanDO> planDOS) {
        planMapper.updateBatch(planDOS);
    }

    @Override
    public void deletePlan(Long id) {
        // 校验存在
        validatePlanChange(id);
        // 删除
        planMapper.deleteById(id);
    }

    @Override
    public void deletePlan(String code) {
        PlanDO planDO = planMapper.selectByCode(code);
        if (ObjectUtil.isNotEmpty(planDO)) {
            deletePlan(planDO.getId());
        }
    }

    /**
     * 校验
     * @param id
     * @param code
     */
    private void validateCreateOrUpdate(Long id, String code){
        validateCodeExists(id, code);
    }

    private void validateCodeExists(Long id, String code){
        PlanDO planDO = planMapper.selectByCode(code);
        if (ObjectUtil.isEmpty(planDO)) {
            return;
        }
        if (id == null) {
            throw exception(PLAN_CODE_EXISTS);
        }
        if (!id.equals(planDO.getId())){
            throw exception(PLAN_CODE_EXISTS);
        }
    }

    private void validatePlanChange(Long id) {
        PlanDO plan = planMapper.selectById(id);
        if (ObjectUtil.isEmpty(plan)) {
            throw exception(PLAN_NOT_EXISTS);
        }
        if (MesPlanStatusEnum.ED.getMesPlanStatus().equals(plan.getStatus())
        || plan.getProduceAmount().compareTo(BigDecimal.ZERO) > 0) {
            throw exception(PLAN_NOT_CHANGE);
        }
    }
    private PlanDO validatePlanExists(Long id) {
        PlanDO plan = planMapper.selectById(id);
        if (plan == null) {
            throw exception(PLAN_NOT_EXISTS);
        }
        return plan;
    }

    @Override
    public PlanDO getPlan(Long id) {
        return planMapper.selectById(id);
    }

    @Override
    public List<PlanDO> getPlanList(Collection<Long> ids) {
        return planMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<PlanDO> getPlanPage(PlanPageReqVO pageReqVO) {
        return planMapper.selectPage(pageReqVO);
    }

    @Override
    public List<PlanDO> getPlanList(PlanExportReqVO exportReqVO) {
        return planMapper.selectList(exportReqVO);
    }

    @Override
    public void changeAmount(Long planId, BigDecimal produceAmount, BigDecimal reportAmount, BigDecimal inAmount) {
        PlanDO plan = validatePlanExists(planId);
        if (produceAmount != null) {
            BigDecimal newProduceAmount = plan.getProduceAmount().add(produceAmount);
            plan.setProduceAmount(newProduceAmount);
            if (newProduceAmount.compareTo(BigDecimal.ZERO) == 0) {
                plan.setStatus(MesPlanStatusEnum.NOT.getMesPlanStatus());
            }
        }
        // TODO 处理报工数量与入库数量
        planMapper.updateById(plan);
    }

    @Override
    public Boolean checkItemUsed(Long id) {
        PlanDO planDO = planMapper.selectOneByItemProduceId(id);
        return ObjectUtil.isNotEmpty(planDO);
    }

}
